{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "gpuType": "T4"
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "EUFtpy81qa7Z"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "from datetime import datetime\n",
        "import glob\n",
        "from PIL import Image\n",
        "import torch\n",
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "from torch.utils.data import DataLoader, Dataset\n",
        "from torchvision import transforms, utils\n",
        "\n",
        "# ========== Paths ==========\n",
        "data_root = \"./dataset/raw/img_align_celeba/img_align_celeba\"\n",
        "save_dir = \"./dataset/save/\"\n",
        "os.makedirs(save_dir, exist_ok=True)\n",
        "\n",
        "# ========== Hyperparams ==========\n",
        "batch_size = 512\n",
        "lr = 2e-4\n",
        "num_epochs = 100\n",
        "latent_dim = 128\n",
        "sample_every = 5\n",
        "num_sample_images = 8\n",
        "image_size = 64\n",
        "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
        "\n",
        "transform = transforms.Compose([\n",
        "    transforms.Resize(image_size),\n",
        "    transforms.CenterCrop(image_size),\n",
        "    transforms.ToTensor(),\n",
        "])"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4598c9de"
      },
      "source": [
        "# import os\n",
        "\n",
        "# # Install the Kaggle API client\n",
        "# !pip install kaggle\n",
        "\n",
        "# # Create the .kaggle directory and copy the kaggle.json file\n",
        "# !mkdir -p ~/.kaggle\n",
        "# # You will need to upload your kaggle.json file to your Colab environment.\n",
        "# # In the left sidebar, click on the folder icon, then click on the upload icon.\n",
        "# # Upload your kaggle.json file there.\n",
        "# # Once uploaded, move it to the correct directory:\n",
        "# # !mv kaggle.json ~/.kaggle/\n",
        "\n",
        "# # If you have stored your Kaggle API key and username as Colab secrets, you can use the following:\n",
        "# from google.colab import userdata\n",
        "\n",
        "# os.environ['KAGGLE_USERNAME'] = userdata.get('KAGGLE_USERNAME')\n",
        "# os.environ['KAGGLE_KEY'] = userdata.get('KAGGLE_KEY')\n",
        "\n",
        "# # Set permissions for the kaggle.json file\n",
        "# !chmod 600 ~/.kaggle/kaggle.json\n",
        "\n",
        "# # Download the dataset\n",
        "# !kaggle datasets download -d jessicali9530/celeba-dataset -p ./dataset/raw --unzip"
      ],
      "execution_count": 14,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# ========== Dataset ==========\n",
        "class CelebADataset(Dataset):\n",
        "    def __init__(self, root, transform=None):\n",
        "        self.root = root\n",
        "        self.paths = sorted(glob.glob(os.path.join(root, \"*.jpg\")))\n",
        "        self.transform = transform\n",
        "\n",
        "    def __len__(self):\n",
        "        return len(self.paths)\n",
        "\n",
        "    def __getitem__(self, idx):\n",
        "        img_path = self.paths[idx]\n",
        "        img = Image.open(img_path).convert(\"RGB\")\n",
        "        if self.transform:\n",
        "            img = self.transform(img)\n",
        "        return img\n",
        "\n",
        "dataset = CelebADataset(root=data_root, transform=transform)\n",
        "loader = DataLoader(dataset, batch_size=batch_size, shuffle=True,\n",
        "                    num_workers=2, pin_memory=True)\n",
        "print(\"Num Images: \", len(dataset))\n",
        "\n",
        "# ========== Utilities ==========\n",
        "def save_checkpoint(model, optim, epoch, path):\n",
        "    state = {\n",
        "        \"epoch\": epoch,\n",
        "        \"model_state\": model.state_dict(),\n",
        "        \"optim_state\": optim.state_dict()\n",
        "    }\n",
        "    torch.save(state, path)\n",
        "\n",
        "\n",
        "def save_image_grid(tensor, filename, nrow=8):\n",
        "    tensor = torch.clamp(tensor, 0, 1)\n",
        "    utils.save_image(tensor, filename, nrow=nrow, padding=2)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "33YgK3i0qtMa",
        "outputId": "e8076b99-f1b2-4650-b49c-3a4a168d34d8"
      },
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Num Images:  202599\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# ========== Loss ==========\n",
        "def vae_loss(recon_x, x, mu, logvar):\n",
        "    recon_loss = F.mse_loss(recon_x, x, reduction='sum') / x.size(0)\n",
        "    kld = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp()) / x.size(0)\n",
        "\n",
        "    # β-VAE: 可以引入一个权重来平衡两项，初期可以设 beta=1\n",
        "    beta = 1.0\n",
        "\n",
        "    return recon_loss + beta * kld, recon_loss, kld\n"
      ],
      "metadata": {
        "id": "2u_MJ6cStwxG"
      },
      "execution_count": 16,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9be1efdc"
      },
      "source": [
        "# ========== VAE Model ==========\n",
        "class VAE(nn.Module):\n",
        "    def __init__(self, latent_dim):\n",
        "        super().__init__()\n",
        "        self.latent_dim = latent_dim\n",
        "        self.encoder = nn.Sequential(\n",
        "            nn.Conv2d(3, 32, 4, 2, 1),\n",
        "            nn.ReLU(),\n",
        "            nn.Conv2d(32, 64, 4, 2, 1),\n",
        "            nn.ReLU(),\n",
        "            nn.Conv2d(64, 128, 4, 2, 1),\n",
        "            nn.ReLU(),\n",
        "            nn.Conv2d(128, 256, 4, 2, 1),\n",
        "            nn.ReLU(),\n",
        "            nn.Flatten(),\n",
        "        )\n",
        "        self.fc_mu = nn.Linear(256 * 4 * 4, latent_dim)\n",
        "        self.fc_logvar = nn.Linear(256 * 4 * 4, latent_dim)\n",
        "\n",
        "        self.decoder_input = nn.Linear(latent_dim, 256 * 4 * 4)\n",
        "        self.decoder = nn.Sequential(\n",
        "            nn.Unflatten(1, (256, 4, 4)),\n",
        "            nn.ConvTranspose2d(256, 128, 4, 2, 1),\n",
        "            nn.ReLU(),\n",
        "            nn.ConvTranspose2d(128, 64, 4, 2, 1),\n",
        "            nn.ReLU(),\n",
        "            nn.ConvTranspose2d(64, 32, 4, 2, 1),\n",
        "            nn.ReLU(),\n",
        "            nn.ConvTranspose2d(32, 3, 4, 2, 1),\n",
        "            nn.Sigmoid(),\n",
        "        )\n",
        "\n",
        "    def encode(self, x):\n",
        "        h = self.encoder(x)\n",
        "        return self.fc_mu(h), self.fc_logvar(h)\n",
        "\n",
        "    def reparameterize(self, mu, logvar):\n",
        "        std = torch.exp(0.5 * logvar)\n",
        "        eps = torch.randn_like(std)\n",
        "        return mu + eps * std\n",
        "\n",
        "    def decode(self, z):\n",
        "        h = self.decoder_input(z)\n",
        "        return self.decoder(h)\n",
        "\n",
        "    def forward(self, x):\n",
        "        mu, logvar = self.encode(x)\n",
        "        z = self.reparameterize(mu, logvar)\n",
        "        return self.decode(z), mu, logvar"
      ],
      "execution_count": 17,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from tqdm import tqdm\n",
        "model = VAE(latent_dim=latent_dim).to(device)\n",
        "optim = torch.optim.Adam(model.parameters(), lr=lr)\n",
        "global_step = 0\n",
        "for epoch in range(1, num_epochs + 1):\n",
        "    model.train()\n",
        "    epoch_loss = 0.0\n",
        "    epoch_recon = 0.0\n",
        "    epoch_kld = 0.0\n",
        "\n",
        "    for batch_idx, imgs in enumerate(tqdm(loader)):\n",
        "        imgs = imgs.to(device, non_blocking=True)\n",
        "        optim.zero_grad()\n",
        "        recon_imgs, mu, logvar = model(imgs)\n",
        "        loss, recon_l, kld = vae_loss(recon_imgs, imgs, mu, logvar)\n",
        "        loss.backward()\n",
        "        optim.step()\n",
        "\n",
        "        epoch_loss += loss.item()\n",
        "        epoch_recon += recon_l.item()\n",
        "        epoch_kld += kld.item()\n",
        "        global_step += 1\n",
        "\n",
        "        if batch_idx % 100 == 0:\n",
        "            print(f\"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] \"\n",
        "                    f\"Epoch {epoch}/{num_epochs} Batch {batch_idx}/{len(loader)} \"\n",
        "                    f\"Loss {loss.item():.4f} \"\n",
        "                    f\"(recon {recon_l.item():.4f}, kld {kld.item():.4f})\")\n",
        "\n",
        "    n_samples = len(loader.dataset)\n",
        "    print(f\"=== Epoch {epoch} finished. Avg loss: {epoch_loss / n_samples:.4f} \"\n",
        "            f\"(recon {epoch_recon / n_samples:.4f}, kld {epoch_kld / n_samples:.4f}) ===\")\n",
        "\n",
        "    # 保存样本\n",
        "    if epoch % sample_every == 0 or epoch == 1:\n",
        "        # 保存检查点\n",
        "        ckpt_path = os.path.join(save_dir, f\"vae_epoch{epoch}.pth\")\n",
        "        save_checkpoint(model, optim, epoch, ckpt_path)\n",
        "        model.eval()\n",
        "        with torch.no_grad():\n",
        "            # 重建样本\n",
        "            imgs = next(iter(loader))\n",
        "            imgs = imgs.to(device)[:num_sample_images]\n",
        "            recon_imgs, _, _ = model(imgs)\n",
        "            combined = torch.cat([imgs, recon_imgs], dim=0)  # 不再需要clamp\n",
        "            save_image_grid(combined, os.path.join(save_dir, f\"recon_epoch{epoch}.png\"), nrow=8)\n",
        "\n",
        "            # 生成样本\n",
        "            z = torch.randn(num_sample_images, latent_dim).to(device)\n",
        "            samples = model.decode(z)\n",
        "            save_image_grid(samples, os.path.join(save_dir, f\"sample_epoch{epoch}.png\"), nrow=8)\n",
        "        model.train()\n",
        "\n",
        "print(\"Training complete.\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        },
        "id": "y1EWwlm8qzPV",
        "outputId": "15c4a24e-8fc1-4eea-8fb7-2ccb3db4dc52"
      },
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "  0%|          | 1/396 [00:01<09:41,  1.47s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:07:41] Epoch 1/100 Batch 0/396 Loss 1135.2826 (recon 1135.2656, kld 0.0170)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 25%|██▌       | 100/396 [00:48<02:05,  2.36it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:08:28] Epoch 1/100 Batch 100/396 Loss 640.2681 (recon 612.3834, kld 27.8847)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 51%|█████     | 200/396 [01:36<02:06,  1.55it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:09:16] Epoch 1/100 Batch 200/396 Loss 415.4881 (recon 371.2596, kld 44.2285)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 76%|███████▌  | 301/396 [02:21<00:36,  2.61it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:10:01] Epoch 1/100 Batch 300/396 Loss 345.3352 (recon 296.2002, kld 49.1350)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "100%|██████████| 396/396 [03:05<00:00,  2.13it/s]\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "=== Epoch 1 finished. Avg loss: 1.0048 (recon 0.9319, kld 0.0729) ===\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "  1%|          | 2/396 [00:01<04:19,  1.52it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:10:49] Epoch 2/100 Batch 0/396 Loss 313.2043 (recon 263.1500, kld 50.0544)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 26%|██▌       | 101/396 [00:47<02:08,  2.29it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:11:35] Epoch 2/100 Batch 100/396 Loss 275.7783 (recon 226.1701, kld 49.6082)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 51%|█████     | 201/396 [01:32<01:36,  2.02it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:12:20] Epoch 2/100 Batch 200/396 Loss 275.4307 (recon 225.6817, kld 49.7490)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 76%|███████▌  | 301/396 [02:21<00:45,  2.08it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:13:09] Epoch 2/100 Batch 300/396 Loss 261.7190 (recon 212.4102, kld 49.3087)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "100%|██████████| 396/396 [03:04<00:00,  2.15it/s]\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "=== Epoch 2 finished. Avg loss: 0.5379 (recon 0.4418, kld 0.0961) ===\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "  0%|          | 1/396 [00:00<06:23,  1.03it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:13:53] Epoch 3/100 Batch 0/396 Loss 249.8823 (recon 200.6285, kld 49.2538)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 26%|██▌       | 101/396 [00:47<02:58,  1.66it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:14:39] Epoch 3/100 Batch 100/396 Loss 246.0801 (recon 194.5008, kld 51.5793)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 51%|█████     | 201/396 [01:32<01:15,  2.58it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:15:25] Epoch 3/100 Batch 200/396 Loss 229.2155 (recon 178.2279, kld 50.9876)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 76%|███████▌  | 301/396 [02:18<00:40,  2.37it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:16:10] Epoch 3/100 Batch 300/396 Loss 230.8549 (recon 178.9533, kld 51.9017)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "100%|██████████| 396/396 [03:03<00:00,  2.16it/s]\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "=== Epoch 3 finished. Avg loss: 0.4586 (recon 0.3590, kld 0.0996) ===\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "  0%|          | 1/396 [00:01<06:51,  1.04s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:16:56] Epoch 4/100 Batch 0/396 Loss 228.4072 (recon 176.4426, kld 51.9646)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 26%|██▌       | 101/396 [00:47<02:05,  2.36it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:17:43] Epoch 4/100 Batch 100/396 Loss 217.3139 (recon 165.6172, kld 51.6967)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 51%|█████     | 201/396 [01:36<01:33,  2.08it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:18:32] Epoch 4/100 Batch 200/396 Loss 222.6495 (recon 170.6667, kld 51.9827)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 76%|███████▌  | 301/396 [02:21<00:42,  2.26it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:19:17] Epoch 4/100 Batch 300/396 Loss 212.5311 (recon 159.8948, kld 52.6363)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "100%|██████████| 396/396 [03:27<00:00,  1.91it/s]\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "=== Epoch 4 finished. Avg loss: 0.4264 (recon 0.3240, kld 0.1023) ===\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "  1%|          | 2/396 [00:01<04:47,  1.37it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:20:24] Epoch 5/100 Batch 0/396 Loss 210.4032 (recon 158.2461, kld 52.1572)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 25%|██▌       | 100/396 [00:49<02:07,  2.32it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:21:12] Epoch 5/100 Batch 100/396 Loss 214.3940 (recon 160.8794, kld 53.5146)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 51%|█████     | 201/396 [01:36<01:47,  1.82it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:21:59] Epoch 5/100 Batch 200/396 Loss 208.2413 (recon 154.6446, kld 53.5968)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 76%|███████▌  | 301/396 [02:24<00:49,  1.90it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:22:47] Epoch 5/100 Batch 300/396 Loss 212.5979 (recon 158.4238, kld 54.1742)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "100%|██████████| 396/396 [03:08<00:00,  2.10it/s]\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "=== Epoch 5 finished. Avg loss: 0.4094 (recon 0.3045, kld 0.1049) ===\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "  1%|          | 2/396 [00:01<03:33,  1.85it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:23:34] Epoch 6/100 Batch 0/396 Loss 205.1887 (recon 151.0585, kld 54.1301)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 26%|██▌       | 101/396 [00:47<02:16,  2.16it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:24:20] Epoch 6/100 Batch 100/396 Loss 208.6403 (recon 154.1043, kld 54.5361)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 51%|█████     | 201/396 [01:34<01:39,  1.96it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:25:07] Epoch 6/100 Batch 200/396 Loss 200.9217 (recon 146.0340, kld 54.8877)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 76%|███████▌  | 301/396 [02:20<00:41,  2.31it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:25:54] Epoch 6/100 Batch 300/396 Loss 203.7509 (recon 148.4366, kld 55.3143)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "100%|██████████| 396/396 [03:03<00:00,  2.16it/s]\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "=== Epoch 6 finished. Avg loss: 0.3989 (recon 0.2915, kld 0.1074) ===\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "  0%|          | 1/396 [00:01<07:59,  1.21s/it]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:26:37] Epoch 7/100 Batch 0/396 Loss 202.6416 (recon 147.2393, kld 55.4023)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 26%|██▌       | 101/396 [00:47<02:03,  2.38it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:27:24] Epoch 7/100 Batch 100/396 Loss 202.9415 (recon 147.1316, kld 55.8100)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 51%|█████     | 201/396 [01:34<01:44,  1.86it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:28:11] Epoch 7/100 Batch 200/396 Loss 200.4318 (recon 144.4507, kld 55.9811)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 76%|███████▌  | 301/396 [02:21<00:40,  2.33it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2025-10-06 09:28:57] Epoch 7/100 Batch 300/396 Loss 200.3324 (recon 143.6122, kld 56.7202)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            " 94%|█████████▍| 373/396 [02:54<00:10,  2.14it/s]\n"
          ]
        },
        {
          "output_type": "error",
          "ename": "KeyboardInterrupt",
          "evalue": "",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
            "\u001b[0;32m/tmp/ipython-input-2858988124.py\u001b[0m in \u001b[0;36m<cell line: 0>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      9\u001b[0m     \u001b[0mepoch_kld\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0.0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m     \u001b[0;32mfor\u001b[0m \u001b[0mbatch_idx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mimgs\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mloader\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     12\u001b[0m         \u001b[0mimgs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mimgs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_blocking\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     13\u001b[0m         \u001b[0moptim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzero_grad\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.12/dist-packages/tqdm/std.py\u001b[0m in \u001b[0;36m__iter__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1189\u001b[0m                     \u001b[0mdt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcur_t\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mlast_print_t\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1190\u001b[0m                     \u001b[0;32mif\u001b[0m \u001b[0mdt\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0mmininterval\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mcur_t\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0mmin_start_t\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1191\u001b[0;31m                         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mlast_print_n\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1192\u001b[0m                         \u001b[0mlast_print_n\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlast_print_n\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1193\u001b[0m                         \u001b[0mlast_print_t\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlast_print_t\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.12/dist-packages/tqdm/std.py\u001b[0m in \u001b[0;36mupdate\u001b[0;34m(self, n)\u001b[0m\n\u001b[1;32m   1240\u001b[0m                     \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_ema_dn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1241\u001b[0m                     \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_ema_dt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1242\u001b[0;31m                 \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrefresh\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlock_args\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlock_args\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1243\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdynamic_miniters\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1244\u001b[0m                     \u001b[0;31m# If no `miniters` was specified, adjust automatically to the\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.12/dist-packages/tqdm/std.py\u001b[0m in \u001b[0;36mrefresh\u001b[0;34m(self, nolock, lock_args)\u001b[0m\n\u001b[1;32m   1345\u001b[0m             \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1346\u001b[0m                 \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_lock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0macquire\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1347\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisplay\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1348\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mnolock\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1349\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_lock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrelease\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.12/dist-packages/tqdm/std.py\u001b[0m in \u001b[0;36mdisplay\u001b[0;34m(self, msg, pos)\u001b[0m\n\u001b[1;32m   1493\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mpos\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1494\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmoveto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpos\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1495\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__str__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmsg\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1496\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mpos\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1497\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmoveto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mpos\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.12/dist-packages/tqdm/std.py\u001b[0m in \u001b[0;36mprint_status\u001b[0;34m(s)\u001b[0m\n\u001b[1;32m    457\u001b[0m         \u001b[0;32mdef\u001b[0m \u001b[0mprint_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    458\u001b[0m             \u001b[0mlen_s\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdisp_len\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 459\u001b[0;31m             \u001b[0mfp_write\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'\\r'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0ms\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m' '\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlast_len\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mlen_s\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    460\u001b[0m             \u001b[0mlast_len\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen_s\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    461\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.12/dist-packages/tqdm/std.py\u001b[0m in \u001b[0;36mfp_write\u001b[0;34m(s)\u001b[0m\n\u001b[1;32m    451\u001b[0m         \u001b[0;32mdef\u001b[0m \u001b[0mfp_write\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    452\u001b[0m             \u001b[0mfp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 453\u001b[0;31m             \u001b[0mfp_flush\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    454\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    455\u001b[0m         \u001b[0mlast_len\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.12/dist-packages/tqdm/utils.py\u001b[0m in \u001b[0;36minner\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m    194\u001b[0m         \u001b[0;32mdef\u001b[0m \u001b[0minner\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    195\u001b[0m             \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 196\u001b[0;31m                 \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    197\u001b[0m             \u001b[0;32mexcept\u001b[0m \u001b[0mOSError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    198\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merrno\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.12/dist-packages/ipykernel/iostream.py\u001b[0m in \u001b[0;36mflush\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    486\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpub_thread\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mschedule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mevt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    487\u001b[0m             \u001b[0;31m# and give a timeout to avoid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 488\u001b[0;31m             \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mevt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwait\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mflush_timeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    489\u001b[0m                 \u001b[0;31m# write directly to __stderr__ instead of warning because\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    490\u001b[0m                 \u001b[0;31m# if this is happening sys.stderr may be the problem.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/lib/python3.12/threading.py\u001b[0m in \u001b[0;36mwait\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m    653\u001b[0m             \u001b[0msignaled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_flag\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    654\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0msignaled\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 655\u001b[0;31m                 \u001b[0msignaled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cond\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwait\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    656\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0msignaled\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    657\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/lib/python3.12/threading.py\u001b[0m in \u001b[0;36mwait\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m    357\u001b[0m             \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    358\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 359\u001b[0;31m                     \u001b[0mgotit\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mwaiter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0macquire\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    360\u001b[0m                 \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    361\u001b[0m                     \u001b[0mgotit\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mwaiter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0macquire\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
          ]
        }
      ]
    }
  ]
}